package edu.cqie.smartfarm.interceptors;

import edu.cqie.smartfarm.constant.CommonConstant;
import edu.cqie.smartfarm.constant.MessageConstant;
import edu.cqie.smartfarm.constant.UserConstant;
import edu.cqie.smartfarm.mapper.properties.JwtProperties;
import edu.cqie.smartfarm.service.IUserService;
import edu.cqie.smartfarm.utils.JwtUtil;
import edu.cqie.smartfarm.utils.ThreadLocalUtil;
import edu.cqie.smartfarm.vo.UserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Component
@RequiredArgsConstructor
@Log4j2
public class LoginInterceptor implements HandlerInterceptor {
    private final StringRedisTemplate stringRedisTemplate;
    private final JwtProperties jwtProperties;
    private final IUserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //令牌验证
        String token = request.getHeader(jwtProperties.getHeader());
        //验证token
        try {
            //从redis中获取相同的token
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            String redisToken = operations.get(CommonConstant.PROJECT_NAME+":"+CommonConstant.USER_TOKEN+":"+token);
            if (redisToken == null) {
                //证明token失效
                throw new RuntimeException();
            }
            // 获取请求路径
            String requestURI = request.getRequestURI();
            // 获取请求方法
            String method = request.getMethod();
            // 获取请求参数
            String queryString = request.getQueryString();
            // 获取ip地址
            String ipAddress = request.getRemoteAddr();
            // 打印日志
            log.info("访问人员为："+ redisToken+
                    "，访问路径为："+requestURI+
                    "，请求方法为："+method+
                    "，请求参数为："+queryString+
                    "，ip地址为："+ipAddress);
            Map<String, Object> claims = JwtUtil.parseJWT(jwtProperties.getSecret(), token);
            Integer userId = (Integer) claims.get(CommonConstant.USER_ID);
            UserVO userVO = userService.getByUserId(userId);
            if (userVO.getStatus()== UserConstant.USER_STATUS_DISABLE){
                // 账号被停用
                throw new RuntimeException();
            }
            //把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(claims);
            //放行
            return true;
        } catch (Exception e) {
            //http响应状态码为401
            response.setStatus(401);
            // 提供响应信息
            response.getWriter().write(MessageConstant.TOKEN_TIME_OUT);
            //拦截
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清除ThreadLocal中的数据
        ThreadLocalUtil.remove();
    }
}
